package org.saratogaschools.edd.firefighter.server;

import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;

import javax.jdo.Extent;
import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;
import javax.jdo.PersistenceManagerFactory;
import javax.jdo.Query;

import org.saratogaschools.edd.firefighter.shared.FireFighterService;
import org.saratogaschools.edd.firefighter.shared.model.Department;
import org.saratogaschools.edd.firefighter.shared.model.Fire;
import org.saratogaschools.edd.firefighter.shared.model.FireFighter;

import com.google.appengine.api.users.User;
import com.google.appengine.api.users.UserService;
import com.google.appengine.api.users.UserServiceFactory;
import com.google.gwt.user.server.rpc.RemoteServiceServlet;

public class FireFighterServiceImpl extends RemoteServiceServlet implements
		FireFighterService {

	private static final long serialVersionUID = 1L;
	private static PersistenceManagerFactory pmf = PMF.get();
	private static UserService userService = UserServiceFactory
			.getUserService();

	@Override
	public FireFighter getFireFighter() {
		User user = userService.getCurrentUser();
		String userId = user.getUserId();
		PersistenceManager pm = pmf.getPersistenceManager();
		try {
			FireFighter fighter = pm.getObjectById(FireFighter.class, userId);
			fighter = pm.detachCopy(fighter);
			return fighter;
		} catch (JDOObjectNotFoundException e) {
			return null;
		} finally {
			pm.close();
		}

	}

	@Override
	public List<Department> getDepartmentList() {
		PersistenceManager pm = pmf.getPersistenceManager();
		Query query = pm.newQuery(Department.class);
		List<Department> toReturn = new LinkedList<Department>();
		Collection<?> results = (Collection<?>) query.execute();
		for (Object result : results) {
			Department detached = (Department) pm.detachCopy(result);
			toReturn.add(detached);
		}
		query.closeAll();
		pm.close();
		return toReturn;
	}

	@Override
	public FireFighter registerFireFighter(FireFighter registrationCandidate) {
		PersistenceManager pm = pmf.getPersistenceManager();
		pm.currentTransaction().begin();
		User user = userService.getCurrentUser();
		String userId = user.getUserId();
		registrationCandidate.setId(userId);
		pm.makePersistent(registrationCandidate);
		FireFighter detached = pm.detachCopy(registrationCandidate);
		pm.currentTransaction().commit();
		pm.flush();
		pm.close();
		return detached;
	}

	@Override
	public Department addDepartment(Department department) {
		PersistenceManager pm = pmf.getPersistenceManager();
		pm.currentTransaction().begin();
		pm.makePersistent(department);
		Department detached = pm.detachCopy(department);
		pm.currentTransaction().commit();
		pm.flush();
		pm.close();
		return detached;
	}

	@Override	
	public Department getDepartmentFromKey(String departmentKey) {
		PersistenceManager pm = pmf.getPersistenceManager();
		Department department = pm.getObjectById(Department.class, departmentKey);
		Department detached = pm.detachCopy(department);
		pm.close();
		return detached;
	}

	@Override
	public void addNewFire(Fire newFire) {
		PersistenceManager pm = pmf.getPersistenceManager();
		pm.currentTransaction().begin();
		// Persist fire
		pm.makePersistent(newFire);
		pm.currentTransaction().commit();
		// Flush and close
		pm.flush();
		pm.close();
				
	}

	@Override
	public List<Fire> getFiresFromDepartment(String departmentKey) {
		PersistenceManager pm = pmf.getPersistenceManager();
		List<Fire> fires = new LinkedList<Fire>();
		Extent<Fire> ext = pm.getExtent(Fire.class);
		for (Fire fire : ext) {
			String dptKey = fire.getManagingDepartmentKey();
			boolean extinguished = fire.isExtinguished();
			if (departmentKey.equals(dptKey) && extinguished == false) {
				Fire detached = pm.detachCopy(fire);
				fires.add(detached);
			}
		}
		ext.closeAll();
		pm.close();
		return fires;
		
	}

	@Override
	public void updateFire(Fire fire) {
		PersistenceManager pm = pmf.getPersistenceManager();
		pm.currentTransaction().begin();
		pm.makePersistent(fire);
		pm.currentTransaction().commit();
		pm.flush();
		pm.close();
	}
}
